/*
 * soc_script_utils.c
 *
 *  Created on: 2019年4月7日
 *      Author: 0yfj0
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "soc_script_types.h"
#include "soc_script_port.h"
#include "soc_script_utils.h"

char *soc_script_exp_dup(char *exp, int len)
{
	int i;
	char *dup;

	dup = _soc_script_malloc(len + 1);
	if (dup != NULL)
	{
		memcpy(dup, exp, len);
        dup[len] = '\0';
		for (i = len - 1; i > 0; --i)
		{
			if (dup[i] != '\r' && dup[i] != ' ')
				break;
		}
	}
	return dup;
}

void soc_script_exp_free(char *exp)
{
	if (exp != NULL)
	{
		_soc_script_free(exp);
	}
}

soc_script_var_t *soc_script_var_malloc(char *name, soc_script_vtype_t type)
{
	int i;
	int sz;
	int len;
	soc_script_var_t *var;

	sz = sizeof(soc_script_var_t);
	if (type == SOC_SCRIPT_BYTES)
	{
		int s;

		for (i = 0, s = -1, len = -1; i < 16; ++i)
		{
			if (name[i] == '[')
			{
				s = i + 1;
			}
			else if (name[i] == ']')
			{
				len = i;
				break;
			}
		}

		if (s > 0 && len > s && len - s <= 4)
		{
			char num[8];

			memcpy(num, &name[s], len - s);
			num[len - s] = '\0';
			if (soc_script_char2bin(num, &len) != 0)
				return NULL;
		}

		if (len <= 0 || len > 2048)
			return NULL;
		sz += len;
	}

	var = (soc_script_var_t*) _soc_script_malloc(sz);
	if (var != NULL)
	{
		snprintf(var->name, sizeof(var->name), name);
		if (type == SOC_SCRIPT_BYTES)
		{
			var->val.v_bytes.ptr = (uint8_t*) var + sizeof(soc_script_var_t);
			var->val.v_bytes.len = len;

			/* buf[100] */
			len = strlen(var->name);
			for (i = 0; i < len; ++i)
			{
				if (var->name[i] == '[')
				{
					var->name[i] = '\0';
					break;
				}
			}
		}
	}
	return var;
}

void soc_script_var_destroy(soc_script_var_t **head)
{
	if (head != NULL || *head != NULL)
	{
		soc_script_var_t *curr;
		soc_script_var_t *next;
		curr = *head;
		while (curr != NULL)
		{
			next = curr->next;
			_soc_script_free(curr);
			curr = next;
		}
	}
}

int soc_script_var_append(soc_script_var_t **head, soc_script_var_t *var)
{
	if (!head || !var)
		return -1;

	if (*head != NULL)
	{
		soc_script_var_t *curr;
		soc_script_var_t *next;
		curr = *head;
		next = curr->next;
		while (next != NULL)
			next = curr->next;
		curr->next = var;
	}
	else
	{
		*head = var;
	}

	return 0;
}

soc_script_var_t *soc_script_var_find(soc_script_var_t *head, char *name)
{
	if (!head || !name)
		return NULL;

	soc_script_var_t *curr = head;
	while (curr != NULL)
	{
		if (strcmp(name, curr->name) == 0)
			return curr;
		curr = curr->next;
	}
	return NULL;
}
